home *** CD-ROM | disk | FTP | other *** search
- Subject: v13i063: Generic user interface kit, Part01/02
- Newsgroups: comp.sources.unix
- Sender: sources
- Approved: rsalz@uunet.UU.NET
-
- Submitted-by: Marc Majka <majka@ubc.csnet>
- Posting-number: Volume 13, Issue 63
- Archive-name: iface/part01
-
- [ This uses BSD tty driver, and will take a bit of grundge to port it
- to SystemV, let alone Version7. --r$ ]
-
- This package contains a "generic" user interface which may be useful.
- It provides word completion, CBREAK I/O, and keybinding. It is
- reasonably easy to tailor to an application. The distributed
- version compiles and runs, and contains a couple of functions
- which demonstrate the flavour of the interface. Cut on the line
- and feed to "sh". It will create the directory "iface" and put
- everything in there.
-
- Manifest:
- comc.c - word completion routine
- exec.c - executive-type functions
- iface.h - header stuff
- fns.c - example functions to demo iface
- init.c - initialization routines
- io.c - input/output routines
- iface.c - main routine
- Makefile - to compile it
- README - describes what it is and how it works
-
- ---
- Marc Majka
-
-
- - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - - CUT - - -
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # iface
- export PATH; PATH=/bin:$PATH
- if test ! -d 'iface'
- then
- mkdir 'iface'
- fi
- cd 'iface'
- if test -f 'comc.c'
- then
- echo shar: will not over-write existing file "'comc.c'"
- else
- cat << \SHAR_EOF > 'comc.c'
- /*
- getcom: get a command (character string) from standard input
- getcom takes a list of character strings in the same format
- as that used for argv, and a count of the number of strings
- in the list, as in argc. It does EMACS-style string
- completion. Getcom returns as its value, the index of the
- command. -1 is returned if the user aborts the completion.
- Note that the command list "clist" must contain its strings
- in sorted order. Also note that getcom expects to have the
- terminal in raw or cbreak mode, with no character echoing.
-
- Characters are read and appended to a command string "cmd".
- Certain characters have special meanings:
-
- ? causes getcom to print all possible completions
- ^G and ESC abort and return -1
- <space>, <tab>, and <return> cause getcom to complete
- <linefeed> causes completion to the first possible string
- <backspace> has the expected result
- <DEL> is treated at <backspace>
- ^U clears the cmd string and restarts completion
-
- */
- #include <stdio.h>
-
- getcom(clist,ncmd,prompt)
- char **clist;
- int ncmd;
- char *prompt;
- {
- int cn,first,last,match,endpt,start,i,c;
- char *entry,cmd[256];
-
- match = endpt = start = first = 0;
- last = ncmd - 1;
- cmd[0] = '\0';
-
- while (!match) {
- c = getchar();
-
- switch(c) {
-
- case '?':
- match = try_match(&first,&last,&start,&endpt,&cn,clist,cmd);
- if (!match) {
- printf("\b \b\n\n");
- helpcom(clist,first,last);
- printf("\n%s %s",prompt,cmd);
- }
- else {
- entry = clist[cn];
- for (i = endpt; entry[i] != '\0'; i++)
- printf("%c",entry[i]);
- }
- break;
-
- case '\07': /* ^G */
- case '\033': /* ESC */
- case '\04': /* ^D */
- return(-1);
-
- case ' ': /* blank */
- case '\t': /* tab */
- case '\r': /* return */
- match = try_match(&first,&last,&start,&endpt,&cn,clist,cmd);
- if (match) {
- entry = clist[cn];
- for (i = endpt; entry[i] != '\0'; i++)
- printf("%c",entry[i]);
- }
- /* else printf("%c",7); */
- break;
-
- case '\n': /* newline */
- match = try_match(&first,&last,&start,&endpt,&cn,clist,cmd);
- if (!strcmp(clist[first],cmd)) {
- cn = first;
- match = 1;
- }
- if (!match) printf("%c",7);
- break;
-
- case '\b': /* backspace */
- case 127: /* DEL */
- if (endpt > 0) {
- printf("\b \b");
- endpt--;
- cmd[endpt] = '\0';
- }
- start = first = 0;
- last = ncmd - 1;
- break;
-
- case '\025': /* ^U */
- for (i = 0; i < endpt; i++) printf("\b \b");
- match = endpt = start = first = 0;
- last = ncmd - 1;
- cmd[0] = '\0';
- break;
-
- default: /* anything else */
- printf("%c",c);
- cmd[endpt++] = c;
- cmd[endpt] = '\0';
- break;
- }
- }
- return(cn);
- }
-
- try_match(f,l,s,p,n,clist,cmd)
- int *f,*l,*s,*p,*n;
- char **clist,*cmd;
- {
- int i,k,tf,tl;
- char *fent,*lent;
-
- if (*p == 0) return(0);
- tf = *f;
- tl = *l;
- k = *p + 1;
- fent = clist[tf];
- lent = clist[tl];
-
- for (i = *s + 1; i < k; i++) {
- fent = clist[tf];
- while ((tf < tl) && (strncmp(cmd,fent,i) > 0)) fent = clist[++tf];
- lent = clist[tl];
- while ((tl > tf) && (strncmp(cmd,lent,i) < 0)) lent = clist[--tl];
- }
-
- if (tf == tl) {
- if (strncmp(cmd,fent,*p) == 0) {
- *f = tf; *l = tl; *s = *p; *n = tf;
- return(1);
- }
- else {
- i = *s;
- while ((i < *p) && (cmd[i] == fent[i])) i++;
- cmd[i] = '\0';
- k = i;
- for (; i < *p; i++) printf("\b \b");
- *p = k;
- return(0);
- }
- }
- else {
- i = *p;
- while (fent[i] == lent[i]) {
- cmd[i] = fent[i];
- printf("%c",cmd[i++]);
- }
- cmd[i] = '\0';
- *f = tf; *l = tl; *p = i; *s = *p;
- return(0);
- }
- }
-
- helpcom(w,f,l)
- char **w;
- int f,l;
- {
- int max, i, len, n;
-
- max = 0;
- for (i = f; i <= l; i++) {
- len = strlen(w[i]);
- if (len > max) max = len;
- }
- n = (l - f) + 1;
-
- printf("? choose one of the following\n");
- printlist(max,n,w+f);
- printf("\n\n");
- printf("? ? for command list\n");
- printf("? ^D, ^G or ESC to exit, ^U to clear\n");
- printf("? <space>, <tab> or <return> to complete\n");
- printf("? <linefeed> to insist on first choice\n");
- }
-
- printlist(size,items,list)
- int size,items;
- char *list[];
- {
- int rows, cols, i, j, x, y, len, n;
- char blank[256];
-
- for (i = 0; i < 256; i++) blank[i] = ' ';
-
- size += 1;
-
- cols = 79 / size;
- rows = items / cols;
- if (items > (rows * cols)) rows++;
- cols = items / rows;
- if (items > (rows * cols)) cols++;
-
- n = rows * cols;
- y = -1;
- x = 0;
-
- for (i = 0; i < n; i++) {
- if (!(i % cols)) {
- printf("\n");
- y++;
- x = y;
- }
- if (x < items) {
- len = strlen(list[x]);
- j = (size - len) + 1;
- blank[j] = '\0';
- printf("%s%s",list[x],blank);
- blank[j] = ' ';
- }
- x += rows;
- }
- }
-
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'exec.c'
- then
- echo shar: will not over-write existing file "'exec.c'"
- else
- cat << \SHAR_EOF > 'exec.c'
- #include "iface.h"
-
- print_version()
- {
- int ref;
-
- ref = sym_ref("version");
- printf("version %s\n",symbol[ref].strval);
- }
-
- exec(ref)
- int ref;
- {
- int (*comptr)();
-
- comptr = cptr[symbol[ref].value];
- (*comptr)();
- }
-
- ESC_prefix()
- {
- int ref;
-
- lastkey = getchar();
- ref = binding[lastkey][1];
- exec(ref);
- }
-
- CTL_X_prefix()
- {
- int ref;
-
- lastkey = getchar();
- ref = binding[lastkey][2];
- exec(ref);
- }
-
- CTL_Y_prefix()
- {
- int ref;
-
- lastkey = getchar();
- ref = binding[lastkey][3];
- exec(ref);
- }
-
- BOGUS()
- {
- putchar('\07');
- }
-
- quit()
- {
- oldterm();
- exit(0);
- }
-
- oldterm()
- {
- ioctl(fileno(stdin),TIOCGETP,&iobasic);
- iobasic.sg_flags = oldflags;
- ioctl(fileno(stdin),TIOCSETP,&iobasic);
-
- ioctl(fileno(stdin),TIOCGLTC,&termc);
- termc.t_suspc = 26;
- termc.t_dsuspc = 25;
- ioctl(fileno(stdin),TIOCSLTC,&termc);
- }
-
- newterm()
- {
- ioctl(fileno(stdin),TIOCGETP,&iobasic);
- oldflags = iobasic.sg_flags;
- iobasic.sg_flags |= CBREAK;
- iobasic.sg_flags &= ~ECHO;
- ioctl(fileno(stdin),TIOCSETN,&iobasic);
-
- ioctl(fileno(stdin),TIOCGLTC,&termc);
- termc.t_suspc = -1;
- termc.t_dsuspc = -1;
- ioctl(fileno(stdin),TIOCSLTC,&termc);
- }
-
- extended_command()
- {
- int cn, ref;
-
- printf(": ");
- cn = getcom(cmds,ncmds,":");
- printf("\n");
- ref = sym_ref(cmds[cn]);
- exec(ref);
- }
-
- sym_ref(name)
- char *name;
- {
- int ref;
-
- if (name == NULL) return(0);
-
- for (ref = 0;
- symbol[ref].name != NULL && strcmp(name,symbol[ref].name);
- ref++);
-
- if (symbol[ref].name != NULL) return(ref);
- return(0);
- }
-
- describe_key()
- {
- char key;
- int tab, ref;
-
- printf("describe-key: ");
- key = getchar();
-
- switch (key) {
- case 27: printf("ESC-"); tab = 1; break;
- case 24: printf("CTL-X-"); tab = 2; break;
- case 25: printf("CTL-Y-"); tab = 3; break;
- default: put_char(key); tab = 0; break;
- }
-
- if (tab) {
- key = getchar();
- put_char(key);
- }
-
- ref = binding[key][tab];
- printf(" is bound to the command \"%s\"\n",symbol[ref].name);
- }
-
- bind_key()
- {
- char key;
- int tab, ref, cn;
-
- printf("bind-key: ");
- key = getchar();
-
- switch (key) {
- case 27: printf("ESC-"); tab = 1; break;
- case 24: printf("CTL-X-"); tab = 2; break;
- case 25: printf("CTL-Y-"); tab = 3; break;
- default: put_char(key); tab = 0; break;
- }
-
- if (tab) {
- key = getchar();
- put_char(key);
- }
-
- printf(" to command: ");
- cn = getcom(cmds,ncmds,"bind-key to command:");
- printf("\n");
- ref = sym_ref(cmds[cn]);
- binding[key][tab] = ref;
- }
-
- describe_bindings()
- {
- int i, k, x, max;
-
- max = 0;
- for (i = 1; i < ncmds; i++) {
- x = strlen(cmds[i]);
- if (x > max) max = x;
- }
-
- for (i = 1; i < ncmds; i++) {
- x = sym_ref(cmds[i]);
- printf("%s",cmds[i]);
- for (k = strlen(cmds[i]); k < max; k++) printf(" ");
- printf(" ");
-
- for (k = 0; k < 128; k++)
- if (binding[k][0] == x) {
- printf(" (");
- put_char(k);
- printf(")");
- }
- for (k = 0; k < 128; k++)
- if (binding[k][1] == x) {
- printf(" (ESC-");
- put_char(k);
- printf(")");
- }
- for (k = 0; k < 128; k++)
- if (binding[k][2] == x) {
- printf(" (CTL-X-");
- put_char(k);
- printf(")");
- }
- for (k = 0; k < 128; k++)
- if (binding[k][3] == x) {
- printf(" (CTL-Y-");
- put_char(k);
- printf(")");
- }
- printf("\n");
- }
- }
-
- dump_symbol_table()
- {
- int i;
-
- for (i = 0; i <= nsyms; i++) {
- printf("%4d: %s ",i,symbol[i].name);
- switch (symbol[i].type) {
- case COMMAND: printf("[command] "); break;
- case VARIABLE: printf("[variable] "); break;
- default: printf("[%d] ",symbol[i].type);
- }
- printf("\"%s\" %d\n",symbol[i].strval,symbol[i].value);
- }
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'iface.h'
- then
- echo shar: will not over-write existing file "'iface.h'"
- else
- cat << \SHAR_EOF > 'iface.h'
- #include <setjmp.h>
- #include <sgtty.h>
- #include <signal.h>
- #include <stdio.h>
- #define NSYM 256
- #define COMMAND 0
- #define VARIABLE 1
- extern char *cmds[256], *syms[NSYM], lastkey;
- extern int (*cptr[256])(), binding[128][4];
- extern int oldflags, ncmds, nsyms;
-
- extern struct ltchars termc;
- extern struct sgttyb iobasic;
- jmp_buf topenv;
- void sigtrap();
- void addcom();
- char *strcpy();
-
- struct sym_struct {
- char *name,*strval;
- int type,value;
- };
- extern struct sym_struct symbol[NSYM];
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'fns.c'
- then
- echo shar: will not over-write existing file "'fns.c'"
- else
- cat << \SHAR_EOF > 'fns.c'
- #include "iface.h"
-
- do_something()
- {
- long random();
- int i;
- char name[128];
-
- i = (int)(random() % 11);
-
- switch (i) {
- case 0: printf("Hello World\n"); break;
- case 1: printf("This space intentionally left blank\n"); break;
- case 2: printf("***REPLACE THIS LINE WITH YOUR MESSAGE***\n"); break;
- case 3: printf("Testing 1, 2, 3, 4\n"); break;
- case 4: printf("Please ignore this message\n"); break;
- case 5: printf("Error\07\n"); break;
- case 6: printf("version 0.0\n"); break;
- case 7: printf("What the hell is a Mimsey Tove?\n"); break;
- case 8: printf("(core not dumped)\n"); break;
- case 9: printf("[ynq] "); put_char(getchar()); printf("\n"); break;
- case 10:
- printf("Please enter your name: ");
- get_string(name);
- printf("\nThank you\n");
- break;
- }
- }
-
- do_nothing() {printf("Done!\n");}
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'init.c'
- then
- echo shar: will not over-write existing file "'init.c'"
- else
- cat << \SHAR_EOF > 'init.c'
- #include "iface.h"
-
- init()
- {
- srandom(getpid());
- signal(SIGINT,sigtrap);
- signal(SIGHUP,sigtrap);
- newterm();
- init_symbols();
- init_variables();
- init_bindings();
- }
-
- init_symbols()
- {
- int i,j;
- char *malloc();
- int (*command_ptr())();
-
- for (i = 0; i < 128; i++)
- for (j = 0; j < 4; j++) binding[i][j] = 0;
-
- nsyms = 0;
- cmds[0] = malloc(6);
- strcpy(cmds[0],"BOGUS");
- cptr[0] = command_ptr("BOGUS");
- symbol[0].name = cmds[0];
- symbol[0].value = 0;
- ncmds = 1;
-
- addcom("CTL-X-prefix");
- addcom("CTL-Y-prefix");
- addcom("ESC-prefix");
- addcom("bind-key");
- addcom("describe-bindings");
- addcom("describe-key");
- addcom("do-nothing");
- addcom("do-something");
- addcom("dump-symbol-table");
- addcom("extended-command");
- addcom("print-version");
- addcom("quit");
- }
-
- init_variables()
- {
- addvar("dummy","",0);
- addvar("version","0.0",0);
- }
-
- void addcom(str)
- char *str;
- {
- char *malloc();
- int ref;
-
- if (strcmp(str,cmds[ncmds-1]) < 0) {
- printf("# Yuck! initial command %s is out of place!\n",str);
- quit();
- }
-
- cmds[ncmds] = malloc((unsigned)(strlen(str)+1));
- strcpy(cmds[ncmds],str);
- cptr[ncmds] = command_ptr(str);
- ncmds++;
-
- for (ref = 1; (ref < NSYM) && (symbol[ref].name != NULL); ref++);
- symbol[ref].name = cmds[ncmds-1];
- symbol[ref].type = COMMAND;
- symbol[ref].value = ncmds-1;
- addsym(symbol[ref].name);
- }
-
- addvar(str,strval,val)
- char *str, *strval;
- int val;
- {
- char *malloc();
- int ref;
-
- for (ref = 1; (ref < NSYM) && (symbol[ref].name != NULL); ref++);
- symbol[ref].name = malloc(strlen(str) + 1);
- strcpy(symbol[ref].name,str);
- symbol[ref].strval = malloc(strlen(strval) + 1);
- strcpy(symbol[ref].strval,strval);
- symbol[ref].type = VARIABLE;
- symbol[ref].value = val;
- addsym(str);
- }
-
- int (*command_ptr(str))()
- char *str;
- {
- int BOGUS(), CTL_X_prefix(), CTL_Y_prefix(), ESC_prefix();
- int quit(), extended_command(), dump_symbol_table();
- int describe_bindings(), describe_key(), bind_key(), print_version();
- int do_something(), do_nothing();
-
- if (!strcmp(str,"BOGUS")) return(BOGUS);
- if (!strcmp(str,"CTL-X-prefix")) return(CTL_X_prefix);
- if (!strcmp(str,"CTL-Y-prefix")) return(CTL_Y_prefix);
- if (!strcmp(str,"ESC-prefix")) return(ESC_prefix);
- if (!strcmp(str,"bind-key")) return(bind_key);
- if (!strcmp(str,"describe-bindings")) return(describe_bindings);
- if (!strcmp(str,"describe-key")) return(describe_key);
- if (!strcmp(str,"do-nothing")) return(do_nothing);
- if (!strcmp(str,"do-something")) return(do_something);
- if (!strcmp(str,"dump-symbol-table")) return(dump_symbol_table);
- if (!strcmp(str,"extended-command")) return(extended_command);
- if (!strcmp(str,"print-version")) return(print_version);
- if (!strcmp(str,"quit")) return(quit);
- return(BOGUS);
- }
-
- addsym(str)
- char *str;
- {
- int i, j, scan;
- char *malloc();
-
- i = 0;
- scan = 1;
-
- while ((scan) && (i < nsyms))
- if (strcmp(str,syms[i]) < 0) scan = 0;
- else i++;
-
- for (j = nsyms; j > i; j--) syms[j] = syms[j-1];
-
- syms[i] = malloc(strlen(str) + 1);
- strcpy(syms[i],str);
- nsyms++;
- }
-
- init_bindings()
- {
- binding[' '][0] = sym_ref("do-something");
- binding['d'][0] = sym_ref("do-something");
- binding['n'][0] = sym_ref("do-nothing");
- binding['q'][0] = sym_ref("quit");
- binding['x'][0] = sym_ref("extended-command");
- binding['x'][1] = sym_ref("extended-command");
- binding[24] [0] = sym_ref("CTL-X-prefix");
- binding[25] [0] = sym_ref("CTL-Y-prefix");
- binding[27] [0] = sym_ref("ESC-prefix");
- binding[27] [1] = sym_ref("quit");
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'io.c'
- then
- echo shar: will not over-write existing file "'io.c'"
- else
- cat << \SHAR_EOF > 'io.c'
- #include <stdio.h>
-
- get_string(str)
- char *str;
- {
- char c;
- int i;
-
- i = 0;
- str[i] = '\0';
-
- while ('\n' != (c = getchar())) {
- switch (c) {
- case 8: /* BACKSPACE */
- if (i > 0) {
- if (str[i-1] < 32 || str[i-1] == 127) printf("\b \b");
- str[--i] = '\0';
- printf("\b \b");
- fflush(stdout);
- }
- break;
- case 127: /* DEL */
- for (i--; i > 0; i--) {
- if (str[i-1] < 32 || str[i-1] == 127) printf("\b \b");
- printf("\b \b");
- }
- str[0] = '\0';
- fflush(stdout);
- break;
- default:
- put_char(c);
- str[i++] = c;
- break;
- }
- }
- str[i] = '\0';
- }
-
- put_char(c)
- char c;
- {
- if (c > 31) {
- if (c == 127) printf("^?");
- else printf("%c",c);
- }
- else printf("^%c",c+64);
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'iface.c'
- then
- echo shar: will not over-write existing file "'iface.c'"
- else
- cat << \SHAR_EOF > 'iface.c'
- #include <setjmp.h>
- #include <sgtty.h>
- #include <signal.h>
- #include <stdio.h>
-
- #define NSYM 256
- #define forever for(;;)
-
- char *cmds[256], *syms[NSYM], lastkey;
- int (*cptr[256])(), binding[128][4];
- int oldflags, ncmds, nsyms;
-
- struct ltchars termc;
- struct sgttyb iobasic;
- jmp_buf topenv;
- void sigtrap();
-
- struct sym_struct {
- char *name,*strval;
- int type,value;
- };
- struct sym_struct symbol[NSYM];
-
-
- main()
- {
- printf("Welcome to interface\n");
- init();
- print_version();
- user_level();
- exit(0);
- }
-
- user_level()
- {
- int ref;
-
- forever {
- if (setjmp(topenv)) printf("top level\n");
- lastkey = getchar();
- ref = binding[lastkey][0];
- exec(ref);
- }
- }
-
- void sigtrap(sig)
- int sig;
- {
- switch(sig) {
- case SIGINT:
- printf("\nInterrupt\n");
- longjmp(topenv,1);
- case SIGHUP:
- quit();
- }
- }
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'Makefile'
- then
- echo shar: will not over-write existing file "'Makefile'"
- else
- cat << \SHAR_EOF > 'Makefile'
- CFLAGS = -O
- BIN=iface
-
- iface: iface.o init.o fns.o exec.o iface.h comc.o io.o
- cc -g -o ${BIN} iface.o init.o fns.o exec.o comc.o io.o
-
- lint:
- lint iface.c init.c fns.c exec.c iface.h comc.c io.c
- SHAR_EOF
- fi # end of overwriting check
- if test -f 'README'
- then
- echo shar: will not over-write existing file "'README'"
- else
- cat << \SHAR_EOF > 'README'
- This directory contains the program iface. Iface is a generic user interface,
- which supports:
-
- - CBREAK mode terminal I/O
- - Keybindings for invoking top-level functions
- - extended-command function invocation
- - Name completion
-
-
- Internally, iface has the following structures:
-
- - 4 keybinding tables for regular keys and ESC, CTL-X and CTL-Y prefix keys
- - A symbol table for command references
-
-
- The interface can be easily extended to any application by adding new functions
- in the file fns.c, adding the names to the symbol table in init_symbols in the
- file init.c, and adding a test to the name-to-function-pointer routine called
- command_ptr, in the file init.c. Key bindings may be made in init_bindings.
-
-
- Several top-level functions exist. They are:
-
- BOGUS: prints a BELL character (^G or \07) causing the terminal to feep.
- generally used as a binding for otherwise unbound keys, or as an
- error function.
-
- CTL-X-prefix: switches to the CTL-X keymap and "executes" the next character.
-
- CTL-Y-prefix: switches to the CTL-Y keymap and "executes" the next character.
-
- ESC-prefix: switches to the ESC keymap and "executes" the next character.
-
- bind-key: changes an entry in a keybinding table.
-
- describe-bindings: prints a list of command names and associaled keybindings
-
- describe-key: prints the command name associated with a key.
-
- extended-command: allows command invocation by name.
-
- quit: resets the terminal and exits.
-
-
- Two commands called "do-something" and "do-nothing" have been included in
- this distribution. They are just there to demonstrate how new commands may
- be added.
-
-
- This interface has proven useful in developing several programs at UBC. Have
- fun with it and feel free to add or change anything. It is all public domain.
- Please leave my name attached. Please don't sell it for profit. Comments and
- suggestions are welcome.
-
- ---
- Marc Majka - UBC Laboratory for Computational Vision
-
- CDN: majka@vision.ubc.cdn
- UUCP: majka@ubc-vision.uucp
- SHAR_EOF
- fi # end of overwriting check
- cd ..
- # End of shell archive
- exit 0
-
-